/**
 * 2015年7月25日上午9:58:23
 * Tools.javaTools
 */
package com.service.tools;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;

import com.service.bean.area.Area;
import com.service.bean.area.PolygonArea;
import com.service.bean.point.Point;

/**
 * 2015年7月25日上午9:58:23
 *
 * 张
 */
public class Tools {
	/**
	 * 计算两点间的距离
	 * @param lng1
	 * @param lat1
	 * @param lng2
	 * @param lat2
	 * @return
	 */
	public static double getTwoPointDistance(double lng1,double lat1,double lng2,double lat2){
	  	double PI=3.1415926535898;
		double R= 6.371229 * (Math.pow(10,6));	
		double x  = (lng2 - lng1) * PI * R * Math.cos( ( (lat1 + lat2) / 2) * PI / 180) / 180;
		double y = (lat2 - lat1) * PI * R / 180;
		double s = Math.sqrt(x * x + y * y);
		return s;
	}
	
	/**
	 * 计算两点间的距离
	 * @param p1
	 * @param p2
	 * @return
	 */
	public static double getTwoPointDistance(Point p1,Point p2){
	  	double PI=3.1415926535898;
		double R= 6.371229 * (Math.pow(10,6));	
		double x  = (p2.baiduLng - p1.baiduLng) * PI * R * Math.cos( ( (p1.baiduLat + p2.baiduLat) / 2) * PI / 180) / 180;
		double y = (p2.baiduLat - p1.baiduLat) * PI * R / 180;
		double s = Math.sqrt(x * x + y * y);
		return s;
	}
	
	/**
	 * 计算点到直线的距离
	 * @param p1 直线起点坐标
	 * @param p2 直线终点坐标
	 * @param p3 点的坐标
	 * @return double 距离
	 */
	public static double pointToLine(Point p1, Point p2, Point p3) {
        double space = 0;
        double a, b, c;
        a = getTwoPointDistance(p1, p2);
        b = getTwoPointDistance(p1, p3);
        c = getTwoPointDistance(p2, p3);      
        if (c+b == a) {
           space = 0;
           return space;
        }  
        if (a <= 0.000001) {
           space = b;
           return space;
        }   
        if (c * c >= a * a + b * b) {
           space = b;
           return space;
        }
        if (b * b >= a * a + c * c) {
           space = c;
           return space;
        }              
        double p = (a + b + c) / 2;
        double s = Math.sqrt(p * (p - a) * (p - b) * (p - c));
        space = 2 * s / a;
        return space;
    }
	
	public static Point getRightTrianglePoint(Point p1, Point p2, double d) {
		double a = new BigDecimal(d / 100000.0D).setScale(8, 4).doubleValue();
		// 纬度
		double x = p1.baiduLat - a * (p2.baiduLng - p1.baiduLng) / Math.sqrt(Math.pow(p2.baiduLat - p1.baiduLat, 2.0D) + Math.pow(p2.baiduLng - p1.baiduLng, 2.0D));
		// 经度
		double y = p1.baiduLng + a * (p2.baiduLat - p1.baiduLat) / Math.sqrt(Math.pow(p2.baiduLat - p1.baiduLat, 2.0D) + Math.pow(p2.baiduLng - p1.baiduLng, 2.0D));
		return new Point(x, y);
	}
	
	/**
	 * 根据前后两个点以及距离确定一个矩形区域
	 * 
	 *    -----------
	 *    |			|(distance)
	 *    *(p1)     *(p2)
	 *    |         |
	 *    -----------
	 * 
	 * @param p1
	 * @param p2
	 * @param distance
	 * @return
	 */
	public static Area getCheckWorkTimeArea(Point p1, Point p2, double distance) {
		Point a = getRightTrianglePoint(p1, p2, distance);
	    Point b = getRightTrianglePoint(p1, p2, -distance);
	    Point c = getRightTrianglePoint(p2, p1, distance);
	    Point d = getRightTrianglePoint(p2, p1, -distance);
	    Area area = new PolygonArea();
	    area.type = 1;
	    area.points.add(a);
	    area.points.add(b);
	    area.points.add(c);
	    area.points.add(d);
	    return area;
	}
	
	/**
	 * 返回上个月的日期
	 */
	public static Date getPreviousMonth(Date date) {
		Calendar cal=Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, -1);

		return cal.getTime();
	}

	/**
	 * 两个日期的时间差(单位秒)
	 * @param start
	 * @param end
	 * @return
	 */
	public static Long getTimeLong(Date start,Date end){
		return (end.getTime()-start.getTime())/1000 ;
	}

	/**
	 * 提供精确的小数位四舍五入处理
	 * @param v 需要四舍五入的数字
	 * @param scale 小数点后保留几位
	 * @return
	 */
	public static double round(double v, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal b = new BigDecimal(Double.toString(v));         
        BigDecimal one = new BigDecimal("1");         
        return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 获取当前线程名称和ID
	 * @return
	 */
	public static String threadInfo() {
		try {
			Thread current = Thread.currentThread();
			return "ThreadName=" + current.getName() + ";ThreadId=" + current.getId();
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 * 获取上一层调用的类名和方法名,1:本方法,2上一层....
	 * @param i
	 * @return
	 */
	public static String[] getMethodName(int i) {
		String[] res = new String[2];
		try {
			StackTraceElement[] temp = Thread.currentThread().getStackTrace();
			StackTraceElement a = (StackTraceElement) temp[i];
			String className = a.getClassName();
			String methodName = a.getMethodName();
			res[0] = className;
			res[1] = methodName;
		} catch (Exception e) {

		}
		return res;
	}
}
